package com.yunpeng.dishes.biz.services.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.yunpeng.dishes.biz.services.IFoodNutrientsService;
import com.yunpeng.dishes.biz.utils.TransformUtil;
import com.yunpeng.dishes.common.vo.FoodNutrientsVO;
import com.yunpeng.dishes.common.vo.NutrientsVO;
import com.yunpeng.dishes.dao.mapper.entity.IFoodIngredientsMapper;
import com.yunpeng.dishes.dao.mapper.entity.INutrientsMapper;
import com.yunpeng.dishes.dao.mapper.relation.IFoodIngredientsNutrientsMapper;
import com.yunpeng.dishes.dao.model.CodeNameDO;
import com.yunpeng.dishes.dao.model.entity.FoodIngredientsDO;
import com.yunpeng.dishes.dao.model.relation.FoodIngredientsNutrientsDO;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * FoodNutrientsServiceImpl 食材营养成分服务
 *
 * @author : Moore(hemw)
 * @date : 2020-03-26
 */
@Service
public class FoodNutrientsServiceImpl implements IFoodNutrientsService {

    /**
     * 食材mapper
     */
    @Resource
    private IFoodIngredientsMapper foodIngredientsMapper;
    /**
     * 食材营养成分表mapper
     */
    @Resource
    private IFoodIngredientsNutrientsMapper foodIngredientsNutrientsMapper;

    /**
     * 获取指定食材的营养成分表
     *
     * @param foodCode
     * @return
     */
    @Override
    public FoodNutrientsVO queryNutrientsOfFoodByCode(String foodCode) {
        FoodIngredientsDO foodIngredientsDO = foodIngredientsMapper.getByCode(foodCode);
        if (foodIngredientsDO == null) {
            return null;
        }
        return getFoodNutrientsVOByFood(foodIngredientsDO);
    }

    @Override
    /**
     * 根据食材名称，获取对应的食材名称、代码列表
     * @param name
     * @return
     */
    public JSONArray queryFoodNames(String name) {
        List<CodeNameDO> codeNameDos = foodIngredientsMapper.queryFoodNames(name);
        if (codeNameDos == null) {
            return null;
        }
        return JSONArray.parseArray(JSON.toJSONString(codeNameDos));
    }

    @Override
    /**
     * 获取指定食材的营养成分表
     * @param foodName
     * @return
     */
    public FoodNutrientsVO queryNutrientOfFoodByName(String foodName) {
        FoodIngredientsDO foodIngredientsDO = foodIngredientsMapper.getByName(foodName);
        if (foodIngredientsDO == null) {
            return null;
        }
        return getFoodNutrientsVOByFood(foodIngredientsDO);
    }

    @Override
    /**
     * 获取指定食材的营养成分表
     * @param id
     * @return
     */
    public FoodNutrientsVO queryNutrientOfFoodById(Long id) {
        FoodIngredientsDO foodIngredientsDO = foodIngredientsMapper.getById(id);
        if (foodIngredientsDO == null) {
            return null;
        }
        return getFoodNutrientsVOByFood(foodIngredientsDO);
    }


    @Override
    /**
     * 批量获取一些食材的营养成分表（最新数据）
     *
     * @param foodIngredientsDOList
     * @return
     */
    public List<FoodNutrientsVO> queryFoodNutrientsByFoods(List<FoodIngredientsDO> foodIngredientsDOList) {
        //空直接返回
        if (foodIngredientsDOList == null || foodIngredientsDOList.isEmpty()) {
            return null;
        }
        Map<String, FoodIngredientsDO> foodsMap = new HashMap<>(16);
        List<String> foodCodeList = new ArrayList<>();
        //处理列表为map，减少查询次数
        for (FoodIngredientsDO foodIngredientsDO : foodIngredientsDOList) {
            foodCodeList.add(foodIngredientsDO.getCode());
            foodsMap.put(foodIngredientsDO.getCode(), foodIngredientsDO);
        }
        //查询食材和营养成分关联关系
        List<FoodIngredientsNutrientsDO> foodIngredientsNutrientsList = foodIngredientsNutrientsMapper.queryForListByFoodCodes(foodCodeList);
        //找不到对应营养成分关联关系，直接返回
        if (foodIngredientsNutrientsList == null || foodIngredientsNutrientsList.isEmpty()) {
            //转化为不包含营养成分的列表返回
            return foodIngredientsDOList.stream().map(x -> TransformUtil.transform(x, null)).collect(Collectors.toList());
        }
        //关联关系map集合
        Map<String, List<NutrientsVO>> foodRelationNutrientsMap = new HashMap<>(16);
        for (FoodIngredientsNutrientsDO foodIngredientsNutrientsDO : foodIngredientsNutrientsList) {
            List<NutrientsVO> nutrientsVOList;
            if (foodRelationNutrientsMap.containsKey(foodIngredientsNutrientsDO.getFoodIngredientsCode())) {
                nutrientsVOList = foodRelationNutrientsMap.get(foodIngredientsNutrientsDO.getFoodIngredientsCode());
            } else {
                nutrientsVOList = new ArrayList<>();
            }
            nutrientsVOList.add(TransformUtil.transform(foodIngredientsNutrientsDO));
            foodRelationNutrientsMap.put(foodIngredientsNutrientsDO.getFoodIngredientsCode(), nutrientsVOList);
        }
        //营养成分表处理
        List<FoodNutrientsVO> resultList = new ArrayList<>();
        for (Map.Entry<String, List<NutrientsVO>> relationEntry : foodRelationNutrientsMap.entrySet()) {
            List<NutrientsVO> voList = relationEntry.getValue();
            resultList.add(TransformUtil.transform(foodsMap.get(relationEntry.getKey()), voList));
        }
        return resultList;
    }

    /**
     * 根据食材获取对应的营养成分表
     *
     * @param foodIngredientsDO
     * @return
     */
    private FoodNutrientsVO getFoodNutrientsVOByFood(FoodIngredientsDO foodIngredientsDO) {
        String foodCode = foodIngredientsDO.getCode();
        //查询食材和营养成分的映射
        Map<String, Object> queryNutrientsParam = new HashMap<>(16);
        queryNutrientsParam.put("food_ingredients_code", foodCode);
        queryNutrientsParam.put("flag", 1);
        List<FoodIngredientsNutrientsDO> foodIngredientsNutrientsList = foodIngredientsNutrientsMapper.queryForList(queryNutrientsParam);
        //找不到对应营养成分关联关系，直接返回
        if (foodIngredientsNutrientsList == null || foodIngredientsNutrientsList.isEmpty()) {
            return TransformUtil.transform(foodIngredientsDO, null);
        }
        //营养成分表处理
        List<NutrientsVO> nutrientsVOList = new ArrayList<>();
        for (FoodIngredientsNutrientsDO foodIngredientsNutrientsDO : foodIngredientsNutrientsList) {
            nutrientsVOList.add(TransformUtil.transform(foodIngredientsNutrientsDO));
        }
        return TransformUtil.transform(foodIngredientsDO, nutrientsVOList);
    }


}
